package com.example.sse.demos.web;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

@RestController
public class SSEOneController {

    // 存储 SSE 发射器，使用 CopyOnWriteArrayList 以支持并发操作
    private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();
    // 标志位，用于控制数据发送
    private final AtomicBoolean running = new AtomicBoolean(false);

    @GetMapping(path = "/sseOne", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter sseEmitter() {
        SseEmitter sseEmitter = new SseEmitter(Long.MAX_VALUE);
        emitters.add(sseEmitter);

        sseEmitter.onCompletion(() -> emitters.remove(sseEmitter));
        sseEmitter.onTimeout(() -> emitters.remove(sseEmitter));
        sseEmitter.onError((e) -> emitters.remove(sseEmitter));

        return sseEmitter;
    }

    @Scheduled(fixedDelay = 1000)
    public void sendData() {
        // 检查是否需要发送数据
        if (!running.get()) {
            return;
        }
        System.out.println("Sending data...");
        String data = "Data at " + System.currentTimeMillis();
        System.out.println("emitters======"+emitters.size());
        if (emitters.size() > 0){
            for (SseEmitter emitter : emitters) {
                try {
                    emitter.send(SseEmitter.event()
                            .data(data));
                } catch (IOException e) {
                    emitters.remove(emitter);
                }
            }
        }
    }

    // 提供一个接口用于控制数据发送的开始和停止
    @GetMapping("/start")
    public String start() {
        running.set(true);
        return "Data sending started.";
    }

    @GetMapping("/stop")
    public String stop() {
        running.set(false);
        return "Data sending stopped.";
    }
}
